package it.uniroma2.orchestrator;

import it.uniroma2.gestoreontologie.Gestore;
import it.uniroma2.model.wizard.Parametri;

import java.io.File;
import java.util.Hashtable;
import java.util.Vector;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class Servizio {
	
	private String nome;
	private String input;
	private String output;
	private String descrizione;
	private String wsdl;
	private String url;
	private int rank;
	private boolean model;
	private String level;
	private String type;
	
	
	private Gestore gestore;
	private String mainOperation;
	private String parameterOperation;
	private Hashtable internalParameter;
	private Hashtable externalParameter;
	private Vector<String> preCondizione;
	private Vector<String> postCondizione;
	
	public Servizio(String nome){
		
		this.gestore = new Gestore(Parametri.NS, "file:G://ProgettiJava//OpinionMiningFramework//provaserviziclass.owl");
		this.rank = 0;
		this.input = new String();
		this.output = new String();
		this.nome = nome;
		this.model = false;
		this.level = new String();
		this.type = new String();
		this.fillService();
	}
	
	public void fillService(){
		this.findMainOperation();
		this.findParameterOperation();
		this.findURL();
		this.findWSDL();
		this.findInternalParameter();
		this.findExternalParameter();
		this.findPreCond();
		this.findPostCond();
		
	}
	private void findMainOperation(){
		this.mainOperation = new String();
		mainOperation = gestore.recuperaDataPro(nome, "Main_Operation");
	}
	
	private void findParameterOperation(){
		this.parameterOperation = new String();
		parameterOperation = gestore.recuperaDataPro(nome, "Parameter_Operation");
	}
	
	private void findInternalParameter(){
		this.internalParameter = new Hashtable();
		Vector<String> propVect = gestore.recuperaProprietaVect(nome, "has_internal_input");
		for (int k = 0; k < propVect.size(); k++){
			String tmp = propVect.elementAt(k);
			String tmp2 = gestore.recuperaProprieta(tmp, "has_type");
			internalParameter.put(tmp, tmp2);
		}
	}
	
	private void findExternalParameter(){
		this.externalParameter = new Hashtable();
		Vector<String> propVect = gestore.recuperaProprietaVect(nome, "has_external_input");
		for (int k = 0; k < propVect.size(); k++){
			String tmp = propVect.elementAt(k);
			String tmp2 = gestore.recuperaProprieta(tmp, "has_type");
			externalParameter.put(tmp, tmp2);
		}
	}
	private void findPreCond(){
		this.preCondizione = new Vector();
		preCondizione = gestore.recuperaProprietaVect(nome, "pre_condition");
	}
	private void findPostCond(){
		this.postCondizione = new Vector();
		postCondizione = gestore.recuperaProprietaVect(nome, "post_condition");
	}
	
	
	private void findURL(){
		this.url = new String();
		url = gestore.recuperaDataPro(nome, "URL");
	}
	
	private void findWSDL(){
		this.wsdl = new String();
		wsdl = gestore.recuperaDataPro(nome, "WSDL");
	}
	
	
	public String getMainOperation(){
		return this.mainOperation;
	}
	
	public String getParameterOperation(){
		return this.parameterOperation;
		
	}
	public String getInput() {
		return input;
	}

	public void setInput(String input) {
		this.input = input;
	}

	public String getOutput() {
		return output;
	}

	public void setOutput(String output) {
		this.output = output;
	}
	public String getNome(){
		return nome;
	}

	public Vector<String> getPreCondizione() {
		return preCondizione;
	}

	public void setPreCondizione(String servizio) {
		this.preCondizione.addElement(servizio);
	}

	public Vector<String> getPostCondizione() {
		return postCondizione;
	}

	public void setPostCondizione(String servizio) {
		this.postCondizione.addElement(servizio);
	}
	
	public String toString(){
		return nome;
	}
	
	public boolean hasPreCondizione(){
		if(this.preCondizione.isEmpty()) return false;
		return true;
	}
	
	public boolean hasPostCondizione(){
		if(this.postCondizione.isEmpty()) return false;
		return true;
	}
	//This method calculates ranks of classifier
	public void rankCalc(String level, String type){
		this.level = level;
		this.type = type;
		if(type.compareToIgnoreCase(Parametri.FEATURE) == 0 || type.compareToIgnoreCase(Parametri.TARGET) == 0){
			if(level.compareToIgnoreCase(Parametri.LVLDOC) == 0){
				this.rank = 1;
			} else if(level.compareToIgnoreCase(Parametri.LVLSENT) == 0){
				this.rank = 2;
			} else if(level.compareToIgnoreCase(Parametri.LVLFEAT) == 0){
				this.rank = 3;
			}
		}else{
			if(level.compareToIgnoreCase(Parametri.LVLDOC) == 0){
				this.rank = 4;
			} else if(level.compareToIgnoreCase(Parametri.LVLSENT) == 0){
				this.rank = 5;
			} else if(level.compareToIgnoreCase(Parametri.LVLFEAT) == 0){
				this.rank = 6;
			}
		}
		
	}
	
	public void createAnnotationFile(){
		
		
		try {
			DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
			
			Document doc = docBuilder.newDocument();
			Element rootElement = doc.createElement("annotation");
			doc.appendChild(rootElement);
			Element tagLevel = doc.createElement("tagLevel");
			rootElement.appendChild(tagLevel);
			
			if(level.compareToIgnoreCase(Parametri.LVLDOC) == 0){
				tagLevel.appendChild(doc.createTextNode("Document"));
			} else if(level.compareToIgnoreCase(Parametri.LVLSENT) == 0){
				tagLevel.appendChild(doc.createTextNode("Sentence"));
			} else if(level.compareToIgnoreCase(Parametri.LVLFEAT) == 0){
				tagLevel.appendChild(doc.createTextNode("Featuring"));
			}
			if(type.compareToIgnoreCase(Parametri.TERNARY)== 0){
				Element polari = doc.createElement("polarities");
				rootElement.appendChild(polari);
				Element pola = doc.createElement("Polarity");
				pola.appendChild(doc.createTextNode("Positive"));
				polari.appendChild(pola);
				Element pola2 = doc.createElement("Polarity");
				pola2.appendChild(doc.createTextNode("Negative"));
				polari.appendChild(pola2);
				Element pola3 = doc.createElement("Polarity");
				pola3.appendChild(doc.createTextNode("Neutral"));
				polari.appendChild(pola3);
				
				TransformerFactory transformerFactory = TransformerFactory.newInstance();
				Transformer transformer = transformerFactory.newTransformer();
				DOMSource source = new DOMSource(doc);
				StreamResult result = new StreamResult(new File("annotation.xml"));
		 
				//StreamResult result = new StreamResult(System.out);
		 
				transformer.transform(source, result);
			}
			
			
		} catch (ParserConfigurationException e) {
			System.out.println("Error creating xml file");
			e.printStackTrace();
		} catch (TransformerConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TransformerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
	
	public int getRank(){
		return this.rank;
	}

	public String getUrl(){
		return this.url;
	}
	public String getWsdl(){
		return this.wsdl;
	}
	public void setUrl(String url){
		this.url = url;
	}
	public void setWsdl(String wsdl){
		this.wsdl = wsdl;
	}
	public boolean getModel(){
		return model;
	}
	public void setModel(boolean model){
		this.model = model;
	}
}
